//==================================================================
//--    3段式状态机（Moore）
//==================================================================


//------------<模块及端口声明>----------------------------------------
module water_led(
	
	input  wire 		sys_clk		,
	input  wire			sys_rst_n	,
	
	output reg [3:0] 	led
   );
	
//------------<reg定义>-------------------------------------------------	
	reg [3:0] 	cur_state;			//定义现态寄存器
	reg [3:0] 	next_state;			//定义次态寄存器
	reg [5:0] 	cnt;

//------------<状态机参数定义>------------------------------------------	
	localparam	led_0 = 4'b1110,
				led_1 = 4'b1101,
				led_2 = 4'b1011,
				led_3 = 4'b0111;
		
//------------<计时模块>------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
		if(!sys_rst_n)
			cnt <= 5'b0;
		else if(cnt == 5'd24)begin  
			cnt <= 5'b0;
			end
		else
			cnt <= cnt + 1'b1;
	end
	
//-----------------------------------------------------------------------
//--状态机第一段：同步时序描述状态转移
//-----------------------------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		cur_state <= led_0;
	else
		cur_state <= next_state;
end 

//-----------------------------------------------------------------------
//--状态机第二段：组合逻辑判断状态转移条件，描述状态转移规律以及输出
//-----------------------------------------------------------------------
always@(*)begin
	case(cur_state)
		led_0:begin 
			if(cnt == 5'd5-1 ) 
				next_state=led_1;
			else 
				next_state=led_0;
			end
		led_1:begin 
			if(cnt == 5'd10-1 ) 
				next_state=led_2;
			else 
				next_state=led_1;
			end
		led_2:begin 
			if(cnt == 5'd15-1 ) 
				next_state=led_3;
			else 
				next_state=led_2;
			end
		led_3:begin 
			if(cnt == 5'd20-1 )
				next_state=led_0;
			else 
				next_state=led_3;
			end
		default:next_state=led_0;	
	endcase
end

//-----------------------------------------------------------------------
//--状态机第三段：时序逻辑描述输出
//-----------------------------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		led <= 4'b1110;
	else
		case(cur_state)
			led_0:	led <= 4'b1110;
			led_1:	led <= 4'b1101;
			led_2:	led <= 4'b1011;	
			led_3:	led <= 4'b0111;
			default:led <= 4'b1110;
		endcase
end

endmodule 
